package com.M10.BE.database;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;

import java.util.HashMap;

public class InveProvider extends ContentProvider {
    private InveDatabaseHelper databasehelper;
    private static final UriMatcher uriMatcher;
    private static HashMap<Integer, String> CodeMapTableName;
    private static HashMap<Integer, String> CodeMapID;


    static {
        //UriMatcher操作
        uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);

        //C_Asset
        uriMatcher.addURI(Constants.AUTHORITY, Constants.TABLE_ASSET, Constants.C_Asset);
        uriMatcher.addURI(Constants.AUTHORITY, Constants.TABLE_ASSET + "/#",
                Constants.C_Asset_ID);

        //C_Inventory
        uriMatcher.addURI(Constants.AUTHORITY, Constants.TABLE_INVENTORY, Constants.C_Inventory);
        uriMatcher.addURI(Constants.AUTHORITY, Constants.TABLE_INVENTORY + "/#",
                Constants.C_Inventory_ID);


        ///**************************
        //HashMap操作
        CodeMapTableName = new HashMap<Integer, String>();
        CodeMapID = new HashMap<Integer, String>();

        //TABLE_ASSET
        CodeMapTableName.put(Constants.C_Asset, Constants.TABLE_ASSET);
        CodeMapID.put(Constants.C_Asset_ID, Constants.ID);

        CodeMapTableName.put(Constants.C_Inventory, Constants.TABLE_INVENTORY);
        CodeMapID.put(Constants.C_Inventory_ID, Constants.ID);
    }

    @Override
    public boolean onCreate() {
        // TODO Auto-generated method stub
        Log.d(Constants.ChanceProvider_TAG, "in onCreate method...");

        /**
         * 只有传进去的Constants.DB_VERSION不一样(这里必须比前一个版本高才可以),才会执行databasehelper里面的onUpgrade方法 
         * 因为是先删除原来的表再重建表，所以会丢失数据库中的所有数据。推荐用在数据库表的字段有增删的这种不得已情况下（一般最好新增表，或者给原来的表预留一些字段）
         */
        databasehelper = new InveDatabaseHelper(getContext(), Constants.DB_NAME, null,
                Constants.DB_VERSION);

        /**
         * databasehelper里面的onCreate方法，只有在程序首次安装并第一次打开时才会执行，后面覆盖安装并第一次打开是不会执行的；
         * 如果数据库的版本未改变，不管你是否增加了表，都不执行此方法，这就导致了新增表无法生成；
         * 因此，我在这里每次程序打开都手动执行databasehelper的onCreate方法，这就解决了在数据库版本未升级，不删除原来的数据库数据的前提下动态增加表。
         */
        databasehelper.onCreate(databasehelper.getWritableDatabase());

        //         测试往表里面增加字段
        //        DBOperTools dbOperTools = DBOperTools.getDbOperTools(getContext());
        //        String columnName = "nickname";
        //        boolean isExists = dbOperTools.checkColumnExistsFunc1(Constants.TABLE_MEET, columnName);
        //        if (!isExists)
        //        {
        //            CLog.d(Constants.ChanceProvider_TAG, "add column nickname in table "
        //                                                + Constants.TABLE_MEET);
        //            dbOperTools.addTableColumn(Constants.TABLE_MEET, columnName, "Varchar(50)");
        //        }

        //如果要在SD卡中创建数据库文件，先做如下的判断和创建相应的目录与文件
        /*        if (!dirPath.exists())
                {
                    dirPath.mkdirs(); //创建目录
                }
                if (!filePath.exists())
                {
                    try
                    {
                        filePath.createNewFile(); //创建文件
                    }
                    catch (IOException e)
                    {
                        CLog.e(Constants.ChanceProvider_TAG, "exception:" + e.getMessage());
                    }
                }*/

        return (databasehelper == null) ? false : true;
    }

    @Override
    public String getType(Uri uri) {
        // TODO Auto-generated method stub
        int code = uriMatcher.match(uri);
        switch (code) {
            case Constants.C_Asset:
            case Constants.C_Inventory:

                return Constants.CONTENT_TYPE;

            case Constants.C_Asset_ID:
            case Constants.C_Inventory_ID:
                return Constants.CONTENT_ITEM_TYPE;

            //下面继续添加
            default:
                throw new IllegalArgumentException("Unknown URI " + uri);
        }
    }

    @Override
    public int delete(Uri uri, String where, String[] args) {
        // TODO Auto-generated method stub

        int count = 0;
        String id;
        int code = uriMatcher.match(uri);
        String tableName;
        String tableID;
        if (code < 0) {
            //处理code为-1（即未匹配）的情况。
            throw new IllegalArgumentException("Unknown URI " + uri);
        }
        //在前面未出错时，才打开数据库
        SQLiteDatabase db = databasehelper.getWritableDatabase(); //这个是在程序目录下创建数据库（系统默认）
        //SQLiteDatabase db = databasehelper.openOrCreateDatabase(filePath); //这个是在SD卡上创建数据库

        switch (code) {
            case Constants.C_Asset:
            case Constants.C_Inventory:

                //这属于整个表
                tableName = CodeMapTableName.get(code);
                count = db.delete(tableName, where, args);
                break;

            case Constants.C_Asset_ID:
            case Constants.C_Inventory_ID:

                //这属于表中ID
                tableName = CodeMapTableName.get(code - Constants.ID_DIVIDE);
                tableID = CodeMapID.get(code);
                id = uri.getPathSegments().get(1);
                count = db.delete(tableName,
                        tableID + "=" + id + (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""),
                        args);
                break;
            default:
                break;
        }

        getContext().getContentResolver().notifyChange(uri, null);
        return count;
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        // TODO Auto-generated method stub
        long rowId;
        String tableName;
        int code = uriMatcher.match(uri);
        if (code < 0 || code > Constants.ID_DIVIDE) {
            //处理code为-1（未匹配）或code为表中ID的情况
            throw new IllegalArgumentException("Unknown URI " + uri);
        }
        //在前面没出错时才打开数据库，这样节省资源
        tableName = CodeMapTableName.get(code);
        SQLiteDatabase db = databasehelper.getWritableDatabase(); //这个是在程序目录下创建数据库（系统默认）
        //SQLiteDatabase db = databasehelper.openOrCreateDatabase(filePath); //这个是在SD卡上创建数据库

        switch (code) {
            case Constants.C_Asset:
            case Constants.C_Inventory:

                // 这里，要注意主键问题，如果插入的记录主键跟表中存在的记录一样，则会插入失败
                rowId = db.insert(tableName, null, values);
                if (rowId > 0) {
                    Uri noteUri = ContentUris.withAppendedId(uri, rowId);
                    getContext().getContentResolver().notifyChange(noteUri, null);
                    return noteUri;
                }
                break;

            //在不出错的情况下，下面这些都是不可能执行的
            case Constants.C_Asset_ID:
            case Constants.C_Inventory_ID:

                break;

            default:
                break;
        }

        throw new SQLException("Failed to insert row into " + uri);
    }

    @Override
    public int bulkInsert(Uri uri, ContentValues[] values) {
        // TODO Auto-generated method stub
        String tableName;
        int code = uriMatcher.match(uri);
        if (code < 0 || code > Constants.ID_DIVIDE) {
            //处理code为-1（未匹配）或code为表中ID的情况
            throw new IllegalArgumentException("Unknown URI " + uri);
        }
        //在前面没出错时才打开数据库，这样节省资源
        tableName = CodeMapTableName.get(code);
        SQLiteDatabase db = databasehelper.getWritableDatabase(); //这个是在程序目录下创建数据库（系统默认）
        //SQLiteDatabase db = databasehelper.openOrCreateDatabase(filePath); //这个是在SD卡上创建数据库

        switch (code) {
            case Constants.C_Asset:
            case Constants.C_Inventory:


                // 这里，要注意主键问题，如果插入的记录主键跟表中存在的记录一样，则会插入失败
                db.beginTransaction();
                try {
                    for (int i = 0; i < values.length; i++) {
                        if (db.insert(tableName, null, values[i]) < 0) {
                            return 0;
                        }
                    }
                    db.setTransactionSuccessful();
                } finally {
                    db.endTransaction();
                }
                return values.length;

            //在不出错的情况下，下面这些都是不可能执行的
            case Constants.C_Asset_ID:
            case Constants.C_Inventory_ID:

                break;

            default:
                break;

        }

        throw new SQLException("Failed to insert row into " + uri);
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
                        String sortOrder) {
        // TODO Auto-generated method stub
        Cursor c = null;
        int code = uriMatcher.match(uri);
        String tableName;
        String tableID;
        String id;

        if (code < 0) {
            //处理code为-1（未匹配）的情况 
            throw new IllegalArgumentException("Unknown URI" + uri);
        }
        //在前面未出错时，才打开数据库
        SQLiteDatabase db = databasehelper.getReadableDatabase(); //这个是在程序目录下创建数据库（系统默认）
        //SQLiteDatabase db = databasehelper.openOrCreateDatabase(filePath); //这个是在SD卡上创建数据库

        switch (code) {
            case Constants.C_Asset:
            case Constants.C_Inventory:

                //这属于整个表
                tableName = CodeMapTableName.get(code);
                c = db.query(tableName, projection, selection, selectionArgs, null, null,
                        sortOrder);
                break;

            case Constants.C_Asset_ID:
            case Constants.C_Inventory_ID:


                //属于表中ID
                tableName = CodeMapTableName.get(code - Constants.ID_DIVIDE);
                tableID = CodeMapID.get(code);
                id = uri.getPathSegments().get(1);
                c = db.query(tableName,
                        projection, tableID + "=" + id
                                + (!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : ""),
                        selectionArgs, null, null, sortOrder);
                break;
            default:
                break;
        }

        //Tell the cursor what uri to watch, so it knows when its source data chances
        if (c != null) {
            c.setNotificationUri(getContext().getContentResolver(), uri);
        }
        return c;
    }

    @Override
    public int update(Uri uri, ContentValues values, String where, String[] args) {
        // TODO Auto-generated method stub
        int count = 0;
        int code = uriMatcher.match(uri);
        String tableName, tableID, id;
        if (code < 0) {
            //处理code 为-1（未匹配）的情况
            throw new IllegalArgumentException("Unknown URI " + uri);
        }
        //前面未出错时再打开数据库，以节省资源 
        SQLiteDatabase db = databasehelper.getWritableDatabase(); //这个是在程序目录下创建数据库（系统默认）
        //SQLiteDatabase db = databasehelper.openOrCreateDatabase(filePath); //这个是在SD卡上创建数据库

        switch (code) {
            case Constants.C_Asset:
            case Constants.C_Inventory:

                //这属于整个表
                tableName = CodeMapTableName.get(code);
                count = db.update(tableName, values, where, args);
                break;

            case Constants.C_Asset_ID:
            case Constants.C_Inventory_ID:

                //这属于表中ID
                tableName = CodeMapTableName.get(code - Constants.ID_DIVIDE);
                tableID = CodeMapID.get(code);
                id = uri.getPathSegments().get(1);
                count = db.update(tableName, values,
                        tableID + "=" + id + (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""),
                        args);
                break;
            default:
                break;
        }

        getContext().getContentResolver().notifyChange(uri, null);
        return count;
    }

}